package com.itcast.demo.completablefuture;

import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RestController
@RequestMapping("/completeableFuture")
public class CompletableFutureTest {

    @PostMapping("/test")
    public void test() {
        // 异常处理 使用exceptionally方法处理异常exceptionally方法可以捕获异步任务中的异常，并返回一个默认值或执行其他操作
        // 使用whenComplete 方法处理异常whenComplete 方法无论任务正常完成还是发生异常，都会触发回调函数。在回调函数中，我们可以检查异常参数并进行相应的处理
//        test1();
//        test2();

        // 使用 join 或 get  allof 方法等待所有异步操作完成
//        test3();

        // 线程管理 CompletableFuture 默认使用ForkJoinPool.commonPool()作为其线程池，如果并发量较大，可能会导致线程池资源不足，从而影响程序的性能
//        test4();

        // 异步调用链
//        test5();


         // 多个异步任务组合
//        test6();


    }

    private static void test6() {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "hello";
        });

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "world";
        });

        CompletableFuture<Void> completableFuture = CompletableFuture.allOf(future1, future2).thenRun(() -> {
            // 组合多个异步任务的结果
            String result = future1.join() + " " + future2.join();
            System.out.println(result);
        });
        completableFuture.join();
    }

    private static void test5() {
        CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            // 模拟异步调用获取数据
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "hello";
        }).thenApply(result -> result + " world");
        future.thenAccept(System.out::println);
    }

    private static void test4() {
        ExecutorService executor = Executors.newFixedThreadPool(10);
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(2000);
                System.out.println(Thread.currentThread().getName());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "hello";
        }, executor);

        CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "world";
        }, executor);

        // 使用 allOf 方法等待所有异步操作完成
        CompletableFuture.allOf(future1, future2);
        String s1 = future1.join();
        String s2 = future2.join();
        System.out.println(s1 + " " + s2);
        System.out.println("All operations completed");
    }

    private static void test3() {
        CompletableFuture<String> future1 = CompletableFuture.supplyAsync((() -> {
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "hello";
        }));

        CompletableFuture<String> future2 = future1.thenApply(result -> result + " world");

        // 在整个操作完成后统一获取结果
        String result = future2.join();

        System.out.println(result);
    }

    private static void test2() {
        CompletableFuture<Object> future = CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException("Oops!");
        }).whenComplete((result, ex) -> {
            if (ex != null) {
                System.out.println("Error occurred: " + ex.getMessage());
            }
        });
        future.join();// 输出：Error occurred: Oops!
    }

    private static void test1() {
        CompletableFuture<Object> future = CompletableFuture.supplyAsync(() -> {
            throw new RuntimeException("Oops!");
        }).exceptionally(ex -> {
            System.out.println("Error occurred: " + ex.getMessage());
            return -1;// 返回默认值
        });
        int result = (int) future.join();// 输出：Error occurred: Oops!
    }

}
